﻿using System;
using System.Linq;
using BrightstarDB.Client;
using BrightstarDB.Storage;
using Sample.Models;

namespace Sample
{
    class Program
    {
        protected readonly string StoreName = "taskdb";
        //protected readonly string BaseConnectionString = "type=embedded;storesdirectory=.";
        protected readonly string BaseConnectionString = "type=rest;endpoint=http://localhost/BrightstarDB";

        private string ConnectionString
        {
            get { return BaseConnectionString + ";storename=" + StoreName; }
        }

        private void InitDb()
        {
            var doc = BrightstarService.GetDataObjectContext(BaseConnectionString);

            if (!doc.DoesStoreExist(StoreName))
            {
                doc.CreateStore(StoreName, persistenceType: PersistenceType.Rewrite);
            }
        }

        private void ShowProjects()
        {
            using (var ctx = new MyEntityContext(ConnectionString))
            {
                foreach (var p in ctx.Projects.OrderBy(x => x.Title))
                {
                    Console.WriteLine(p);
                    ShowTasks(p.Id);
                    Console.WriteLine("---");
                }
            }
        }

        private void ShowTasks(string projectId)
        {
            using (var ctx = new MyEntityContext(ConnectionString))
            {
                var p = ctx.Projects.FirstOrDefault(x => x.Id == projectId);
                if (p == null) throw new Exception("Not found");
                foreach (var t in p.Tasks.OrderBy(x => x.Title))
                {
                    Console.WriteLine(t);
                }
            }
        }

        private void ShowStats()
        {
            Console.WriteLine("---Stats---");
            using (var ctx = new MyEntityContext(ConnectionString))
            {
                var projectCount = ctx.Projects.Count();
                var taskCount = ctx.Tasks.Count();
                var stats = string.Format("{0} projects, {1} tasks", projectCount, taskCount);
                Console.WriteLine(stats);
            }
        }

        private void AddProject(string projectTitle)
        {
            using (var ctx = new MyEntityContext(ConnectionString))
            {
                var p = ctx.Projects.Create();
                p.Title = projectTitle;
                ctx.SaveChanges();
            }
        }

        private void AddTask(string projectId, string taskTitle, int taskHoursEffort)
        {
            using (var ctx = new MyEntityContext(ConnectionString))
            {
                ctx.SavingChanges += LastModifiedUpdater.SavingChanges;

                var pp = ctx.Projects.FirstOrDefault(x => x.Id == projectId);
                if (pp == null) throw new Exception("Not found");
                var task = ctx.Tasks.Create();
                task.Title = taskTitle;
                task.HoursEffort = taskHoursEffort;
                pp.Tasks.Add(task);
                ctx.SaveChanges();
            }
        }

        private void UpdateTask(string taskId, string title = null, int hoursEffort = 0, bool isComplete = false)
        {
            using (var ctx = new MyEntityContext(ConnectionString))
            {
                ctx.SavingChanges += LastModifiedUpdater.SavingChanges;

                var task = ctx.Tasks.FirstOrDefault(x => x.Id == taskId);
                if (task == null) throw new Exception("Not found");
                if (title != null) task.Title = title;
                if (hoursEffort != 0) task.HoursEffort = hoursEffort;
                task.IsComplete = isComplete;
                ctx.SaveChanges();
            }
        }

        private void DeleteTask(string taskId)
        {
            using (var ctx = new MyEntityContext(ConnectionString))
            {
                var task = ctx.Tasks.FirstOrDefault(x => x.Id == taskId);
                if (task == null) throw new Exception("Not found");
                ctx.DeleteObject(task);
                ctx.SaveChanges();
            }
        }



        private static void TestSample()
        {
            var p = new Project() {Title = "Demo Project"};
         
            p.Tasks.Add(new Task() {HoursEffort = 2});
            p.Tasks.Add(new Task() {HoursEffort = 3});

            Console.WriteLine("Project title: {0}", p);
            Console.WriteLine("Project total remaining effort: {0}", p.TotalRemainingEffort);
        }

        static void Main(string[] args)
        {
            if (args == null) throw new ArgumentNullException("args");
            //TestSample();
            var program = new Program();
            program.InitDb();
            //program.AddProject("Project1");
            //program.AddTask("b1785d40-0196-41ae-8e0d-eecc2d3ab114", "first task", 3);
            //program.UpdateTask("77f309f7-cd48-4360-b01d-875a06a60c81", hoursEffort: 13, title: "task13", isComplete: true);
            //program.DeleteTask("e2d86bf2-bb0a-40aa-83bd-1611660c91ef");
            program.ShowProjects();
            program.ShowStats();
            Console.WriteLine("Done");
        }
    }
}
